home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 476-500 / disk_497 / nlcalc / source / cmain.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  9KB  |  328 lines

  1. /*
  2.  *  CALC      Provides a calculator that opens on the active screen when
  3.  *            you press a specific key sequence.  Otherwise, the program
  4.  *            waits quitely in the background.
  5.  *
  6.  *              Copyright 1989 by Davide P. Cervone.
  7.  *  You may use this code, provided this copyright notice is kept intact.
  8.  */
  9.  
  10. #define INTUITION_PREFERENCES_H         /* don't need 'em */
  11. #include <intuition/intuitionbase.h>
  12. #include <libraries/dos.h>
  13. #include <proto/intuition.h>
  14. #include <proto/exec.h>
  15.  
  16. #include "cHandler.h"
  17. #include "cSetup.h"
  18. #include "cKeys.h"
  19.  
  20. #define SCREENTITLE\
  21.    "Screen Calculator v3.1    Copyright (c) 1989 by Davide P. Cervone"
  22.  
  23. #define SIGNALCLOSE      TRUE
  24. #define NOSIGNAL         FALSE
  25.  
  26. #define INTUITION_REV    0
  27. #define GRAPHICS_REV     0
  28. #define ERROR_EXIT      10
  29.  
  30.  
  31. #define GADGFLAGS       WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH
  32. #define IDCMPFLAGS\
  33.    CLOSEWINDOW | GADGETUP | GADGETDOWN | VANILLAKEY |\
  34.    NOCAREREFRESH | ACTIVEWINDOW
  35.  
  36. struct IntuitionBase *IntuitionBase;
  37. struct GfxBase *GfxBase;
  38.  
  39. static struct NewWindow NewWindow =
  40. {
  41.    -1,-1, WINDW,WINDH, -1,-1, IDCMPFLAGS,
  42.    SIMPLE_REFRESH | ACTIVATE | GADGFLAGS, NULL, NULL,
  43.  
  44. #ifdef SWINDOWS
  45.    "::",
  46. #else
  47.    NULL,
  48. #endif
  49.  
  50.    NULL, NULL, 20,20, -1,-1, WBENCHSCREEN
  51. };
  52.  
  53.  
  54. struct Screen *CalcScreen;      /* the screen containing the calculator */
  55. struct Window *CalcWindow;      /* the calculator window */
  56. struct RastPort *rp;            /* the windows' rast port */
  57. static LONG CalcWMask;          /* the calculator handler task */
  58.  
  59.  
  60. /*
  61.  *  CloseCalcWindow()
  62.  *
  63.  *  If the window is open, save the calculator position for later, and
  64.  *  close the window.  Clear the pointers to the screen and window, and
  65.  *  forget which signal we used to use for the window.
  66.  *
  67.  *  If we were supposed to let someone know when the window was closed,
  68.  *  then signal the proper task.
  69.  */
  70.  
  71. void CloseCalcWindow(signal)
  72. int signal;
  73. {
  74.    if (CalcWindow != NULL)
  75.    {
  76.       NewWindow.LeftEdge = CalcWindow->LeftEdge;
  77.       NewWindow.TopEdge  = CalcWindow->TopEdge;
  78.       CloseWindow(CalcWindow);
  79.       CalcWindow = NULL;
  80.       CalcScreen = NULL;
  81.       CalcWMask = 0;
  82.    }
  83. #ifndef SWINDOWS
  84.    if (signal) SignalClosed();
  85. #endif
  86. }
  87.  
  88.  
  89. /*
  90.  *  OpenCalcWindow()
  91.  *
  92.  *  If we have a screen to open on, then set the window type and screen
  93.  *  pointer.  Check that the calculator is positioned within the given
  94.  *  screen size.  Open the calulator.  If we were successful, then get the
  95.  *  rastport pointer, and set the mask for the message port.
  96.  */
  97.  
  98. static void OpenCalcWindow(theScreen)
  99. struct Screen *theScreen;
  100. {
  101.    extern struct Window *OpenWindow();
  102.  
  103.    if (theScreen)
  104.    {
  105.       CalcScreen = theScreen;
  106. #ifndef NL_DAEMON
  107.       if (theScreen->BitMap.Depth == 1)
  108.       {
  109.          NewWindow.DetailPen = 0;
  110.          NewWindow.BlockPen  = 1;
  111.       } else {
  112.          NewWindow.DetailPen = DARKPEN;
  113.          NewWindow.BlockPen  = BACKPEN;
  114.       }
  115. #endif
  116. #ifndef SWINDOWS
  117.       NewWindow.Screen = CalcScreen;
  118.       NewWindow.Type   = CUSTOMSCREEN;
  119. #endif
  120.       if (NewWindow.LeftEdge < 0 || NewWindow.TopEdge < 0 ||
  121.           NewWindow.LeftEdge + NewWindow.Width > CalcScreen->Width ||
  122.           NewWindow.TopEdge + NewWindow.Height > CalcScreen->Height)
  123.       {
  124.          NewWindow.LeftEdge = (CalcScreen->Width - NewWindow.Width)/2;
  125.          NewWindow.TopEdge = (CalcScreen->Height - NewWindow.Height)/2;
  126.          if (NewWindow.LeftEdge < 0) NewWindow.LeftEdge = 0;
  127.          if (NewWindow.TopEdge  < 0) NewWindow.TopEdge  = 0;
  128.       }
  129.       if ((CalcWindow = OpenWindow(&NewWindow)) != NULL)
  130.       {
  131.          rp = CalcWindow->RPort;
  132.          CalcWMask = (1<<CalcWindow->UserPort->mp_SigBit);
  133.          CalcScreen = CalcWindow->WScreen;
  134.       } else {
  135.          DisplayBeep(theScreen);
  136.       }
  137.    }
  138. }
  139.  
  140.  
  141. /*
  142.  *  SetupGadgets()
  143.  *
  144.  *  This fixes the standard Intuition gadgets so that their images are
  145.  *  the New Look images.  This makes the Calulator look cool.  Once
  146.  *  the changes have been made, refresh the window frame so that the new
  147.  *  gadgets show up, then add the rest of the Calc gadgets into the window, 
  148.  *  and refresh them so that they show up.
  149.  */
  150.  
  151. static void SetupGadgets()
  152. {
  153. #ifndef NL_DAEMON
  154.    struct Gadget *theGadget = CalcWindow->FirstGadget;
  155.    extern struct Image UpFrontImage,DownBackImage,CloseImage;
  156.    
  157.    while (theGadget)
  158.    {
  159.       switch(theGadget->GadgetType & ~SYSGADGET)
  160.       {
  161.          case WUPFRONT:
  162.             if (CalcScreen->BitMap.Depth > 1)
  163.             {
  164.                theGadget->GadgetRender = (APTR)&UpFrontImage;
  165.                theGadget->LeftEdge = -UpFrontImage.Width + 1;
  166.                theGadget->Width = UpFrontImage.Width;
  167.             }
  168.             break;
  169.  
  170.          case WDOWNBACK:
  171.             if (CalcScreen->BitMap.Depth > 1)
  172.             {
  173.                theGadget->GadgetRender = (APTR)&DownBackImage;
  174.                theGadget->LeftEdge = -UpFrontImage.Width-DownBackImage.Width+1;
  175.                theGadget->Width = DownBackImage.Width;
  176.             }
  177.             break;
  178.  
  179.          case CLOSE:
  180.             theGadget->GadgetRender = (APTR)&CloseImage;
  181.             theGadget->LeftEdge = 0;
  182.             theGadget->Width = CloseImage.Width;
  183.             break;
  184.       }
  185.       theGadget = theGadget->NextGadget;
  186.    }
  187.    RefreshWindowFrame(CalcWindow);
  188. #endif
  189.    AddGList(CalcWindow,&CalcGadget[0],-1,GADGET_COUNT,NULL);
  190.    RefreshGadgets(&CalcGadget[0],CalcWindow,NULL);
  191. }
  192.  
  193. #define CloseCalculator     CloseCalcWindow
  194.  
  195. /*
  196.  *  OpenCalculator()
  197.  *
  198.  *  If the active screen is not the one where the calculator already exists,
  199.  *  then if the calculator is already open, close it (don't signal anyone).
  200.  *  Open the calculator on the new screen.  If the calculator opened OK, 
  201.  *  the setup the gadgets and set the screen title.
  202.  */
  203.  
  204. static void OpenCalculator()
  205. {
  206.    if (IntuitionBase->ActiveScreen != CalcScreen)
  207.    {
  208.       if (CalcWindow) CloseCalculator(NOSIGNAL);
  209.       OpenCalcWindow(IntuitionBase->ActiveScreen);
  210.       if (CalcWindow)
  211.       {
  212.          SetupGadgets();
  213.          SetWindowTitles(CalcWindow,-1,SCREENTITLE);
  214.       }
  215.    }
  216. }
  217.  
  218.  
  219. /*
  220.  *  WaitForAction()
  221.  *
  222.  *  The main Calculator event loop.
  223.  *
  224.  *  While we have not been asked to exit,
  225.  *    if the calc window is open somewhere,
  226.  *      Check for new messages from the calculator window.
  227.  *      If any (and the calculator hasn't been closed or asked to exit) then
  228.  *        get the class code and gadget pointer from the IntuiMessage,
  229.  *        and reply the message.
  230.  *        For CLOSWINDOW events, set the flag indicating we should close.
  231.  *        For keyboard messages, do the appropriate action.
  232.  *        For gadget messages, do the proper gadget action.
  233.  *        For activation events, refresh the lines in the Drag Bar.
  234.  *      When all the messages have been processed,
  235.  *      if we were asked to close the window, then do so.
  236.  *    If we haven't been asked to exit, then wait for more messages.
  237.  *    If we get an ENDSIGNAL from the loader, set the done flag.
  238.  *    If we get a signal to open the calculator, then do so.
  239.  *    If we get a signal to close the calculator (from a CloseScreen
  240.  *      call), then do so.
  241.  */
  242.  
  243. #define NEWMESSAGE      (theMessage = GetMsg(CalcWindow->UserPort))
  244. #ifndef SWINDOWS
  245. #define MESSAGEWAIT     Wait(CalcSMask|CalcCMask|CalcWMask|ENDSIGNAL)
  246. #else
  247. #define MESSAGEWAIT     Wait(CalcSMask|CalcWMask|ENDSIGNAL)
  248. #endif
  249.  
  250. static void WaitForAction()
  251. {
  252.    struct IntuiMessage *theMessage;
  253.    extern struct IntuiMessage *GetMsg();
  254.    int Class, Code;
  255.    struct Gadget *theGadget;
  256.    LONG Signals;
  257.    int NotClosed;
  258.    int NotDone = TRUE;
  259.  
  260.    while (NotDone)
  261.    {
  262.       if (CalcWindow)
  263.       {
  264.          NotClosed = TRUE;
  265.          while (NEWMESSAGE && NotDone && NotClosed)
  266.          {
  267.             Class = theMessage->Class;
  268.             Code  = theMessage->Code;
  269.             theGadget = (struct Gadget *)theMessage->IAddress;
  270.             ReplyMsg(theMessage);
  271.  
  272.             switch(Class)
  273.             {
  274.                case CLOSEWINDOW:
  275.                   NotClosed = FALSE;
  276.                   break;
  277.  
  278.                case VANILLAKEY:
  279.                   NotClosed = DoKey(Code);
  280.                   break;
  281.  
  282.                case GADGETUP:
  283.                case GADGETDOWN:
  284.                   DoGadget(theGadget);
  285.                   break;
  286.  
  287.                case ACTIVEWINDOW:
  288.                   RefreshGList(&CalcGadget[GADG_BRDR],CalcWindow,NULL,1);
  289.                   break;
  290.             }
  291.          }
  292.          if (NotClosed == FALSE) CloseCalculator(NOSIGNAL);
  293.       }
  294.       if (NotDone) Signals = MESSAGEWAIT;
  295.       if (Signals & ENDSIGNAL) NotDone = FALSE;
  296.       if (Signals & CalcSMask) OpenCalculator();
  297. #ifndef SWINDOWS
  298.       if (Signals & CalcCMask) CloseCalculator(SIGNALCLOSE);
  299. #endif
  300.    }
  301. }
  302.  
  303.  
  304. /*
  305.  *  _main()
  306.  *
  307.  *  Initialize the calculator.
  308.  *  As long as we have not been asked to exit, do the main event loop.
  309.  *  Once the main event loop end, we have been asked to exit this task.
  310.  *  close the calculator if it is open, and try to confirm with the loader
  311.  *  that we can exit properly.  If not, then keep running, otherwise
  312.  *  call our exit routine.
  313.  */
  314.  
  315. void _main()
  316. {
  317.    int NotDone = TRUE;
  318.  
  319.    InitCalc();
  320.    while (NotDone)
  321.    {
  322.       WaitForAction();
  323.       CloseCalculator(NOSIGNAL);
  324.       NotDone = ConfirmExit();
  325.    }
  326.    cExit();
  327. }
  328.